package com.catmiw.swt;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import com.catmiw.wyz.util.ExcelUtils;

class MyChar{
	public MyChar(){}
	public MyChar(char c,int priority){
		this.c=c;
		this.priority=priority;
	}
	private char c;
	private int priority;
	public char getC() {
		return c;
	}
	public void setC(char c) {
		this.c = c;
	}
	public int getPriority() {
		return priority;
	}
	public void setPriority(int priority) {
		this.priority = priority;
	} 
	
	public boolean equals(Object o){
		if (!(o instanceof MyChar))
			return false;
		MyChar cc=(MyChar)o;
		return cc.c==c;
	}
}

public class DialogCopybook extends BasicDialog {
	public DialogCopybook(Shell parent) {
		super(parent);
		rowposition=new int[]{20,20,52,8};
		columnposition=new int[]{50,50};
	}

	private static int COLUMNCOUNT=10;

	@Override
	public void setProperties(Properties properties) {
		this.properties = properties;
		setNewcharList(loadNewCharTable(properties.getProperty("生字表文件名"),"GBK"));
		maxChars=Integer.parseInt(properties.getProperty("字帖.每页字数限制"));
		grayChars=Integer.parseInt(properties.getProperty("字帖.蒙版字数量"));
		copybookModelDir=properties.getProperty("模版.目录");
		copybookDir=properties.getProperty("输出目录.字帖");
		
		loadUsedChar();
	}

	private int maxChars=0;
	private int grayChars=0;
	private List<NewCharTable> newcharList;
	
	public List<NewCharTable> getNewcharList() {
		return newcharList;
	}

	public void setNewcharList(List<NewCharTable> newcharList) {
		this.newcharList = newcharList;
	}

	private List<String> booklist=new ArrayList<String>();
	private List<MyChar> charlist=new ArrayList<MyChar>();
	private List<Character> chooseCharList=new LinkedList<Character>();
	
	private Button[] btFont;
	private Button[] btCellPattern;
	private Button[] btRange;
	private Combo cmbBook;
	private String choosebook=null;
	private Combo cmbUnitb;
	private int chooseunitb=-1;
	private Combo cmbUnite;
	private int chooseunite=-1;
	private Composite cpChartable;
	private Button btSelectAll;
	private Button btConfirm;
	private Button btQuit;
	private Button[] btChars;
	private Label lbMessage;
	
	public Composite createCommandButtons(Composite parent){
		Composite composite=new Composite(parent,SWT.NONE);
		composite.setLayout(new FormLayout());
		
		lbMessage=new Label(composite,SWT.NONE);
		
		FormData data=new FormData();
		data.left = new FormAttachment(0,COMPOSITESPACE); 
		data.right = new FormAttachment(50,0-COMPOSITESPACE); 
		lbMessage.setLayoutData(data);
		
		btSelectAll=new Button(composite,SWT.NONE);
		btSelectAll.setText("全选");

		btConfirm=new Button(composite,SWT.NONE);
		btConfirm.setText("生成");
		
		btQuit=new Button(composite,SWT.NONE);
		btQuit.setText("退出");
		
		data=new FormData();
		data.right = new FormAttachment(100,0-COMPOSITESPACE); 
		btQuit.setLayoutData(data);
		
		data=new FormData();
		data.right = new FormAttachment(btQuit,0-COMPOSITESPACE); 
		btConfirm.setLayoutData(data);
		
		data=new FormData();
		data.right = new FormAttachment(btConfirm,0-COMPOSITESPACE); 
		btSelectAll.setLayoutData(data);
		
		return composite;
	}
	
	@Override
	public void addListeners() {
		cmbBook.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e) {
				String choose=cmbBook.getItem(cmbBook.getSelectionIndex());
				if (!choose.equals(choosebook)){
					choosebook=choose;
					bookChanged(choose);
				}
			}
		});
		cmbUnitb.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e) {
				int choose=cmbUnitb.getSelectionIndex();
				if (chooseunitb!=choose){
					chooseunitb=choose;
					unitBeginChanged(choose);
				}
			}
		});
		cmbUnite.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e) {
				int choose=cmbUnite.getSelectionIndex();
				if (chooseunite!=choose){
					chooseunite=choose;
					unitEndChanged(choose);
				}
			}
		});
		
		for (Button range:btRange){
			range.addSelectionListener(new SelectionAdapter(){
				public void widgetSelected(SelectionEvent e) {
					if (null!=choosebook&&chooseunitb>=0&&chooseunitb>=0){
						clearCharTable();
						updateCharTable();
					}
				}
			});
		}
		
		btQuit.addMouseListener(new MouseAdapter() { 
			public void mouseUp(MouseEvent e) {
				shell.dispose();
			} 
		});
		
		btConfirm.addMouseListener(new MouseAdapter() { 
			public void mouseUp(MouseEvent e) {
				String rtn=createCopybook();
				if (rtn!=null){
					messagebox("错误",rtn);
				} else {
					messagebox("提示","生成字帖完成！");
				}
			} 
		});
		
		btSelectAll.addMouseListener(new MouseAdapter() { 
			public void mouseUp(MouseEvent e) {
				selectCharsAll();
			} 
		});
	}

	private void selectCharsAll(){
		chooseCharList.clear();
		for (Button b:btChars){
			if (b.getSelection()){
				b.setSelection(false);
			} else {
				b.setSelection(true);
				chooseCharList.add(b.getText().charAt(0));
			}
		}
		lbMessage.setText("共选中[ "+chooseCharList.size()+"/"+maxChars+" ]个字.");
	}
	
	@Override
	public void createContents() {
		shell.setText("字帖生成器");
		shell.setLayout(new FormLayout());
		
		String fontname[]=((String)properties.get("字帖.字体")).split(",");
		btFont=new Button[fontname.length];
		Group groupFont=createGroupRadioChooser(shell,btFont,"选择字体",fontname,SWT.RADIO,0);
		setPosition(groupFont,1,1);
		
		String cellstyle[]={"方格","田字格","米字格"};
		btCellPattern=new Button[cellstyle.length];
		Group groupCellStyle=createGroupRadioChooser(shell,btCellPattern,"选择格子样式",cellstyle,SWT.RADIO,1);
		setPosition(groupCellStyle,1,2);
				
		Group groupBookUnit=new Group(shell, SWT.SHADOW_OUT);
		groupBookUnit.setText("选择课本及单元");
		groupBookUnit.setLayout(new GridLayout(1,false));
		setPosition(groupBookUnit,2,1);

		String[] bks=new String[booklist.size()];
		for (int i=0;i<booklist.size();i++){
			bks[i]=booklist.get(i);
		}
		cmbBook=createComboChooser(groupBookUnit,"课本:",SWT.READ_ONLY,bks,"");
		
		Composite unitchoose=new Composite(groupBookUnit,SWT.NONE);
		unitchoose.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		String[] units=new String[]{"-1"};
		cmbUnitb=createComboChooser(unitchoose,"单元:",SWT.READ_ONLY,units,"");
		cmbUnite=createComboChooser(unitchoose,"~",SWT.READ_ONLY,units,"");
		
		String chooserange[]={"写字表","认字表","查字表"};
		btRange=new Button[chooserange.length];
		Group groupChooseRange=createGroupCheckChooser(shell,btRange,"选字范围",chooserange,SWT.CHECK,new int[]{0});
		setPosition(groupChooseRange,2,2);

		ScrolledComposite sc=new ScrolledComposite(shell, SWT.H_SCROLL| SWT.V_SCROLL | SWT.BORDER);
		cpChartable=new Composite(sc,SWT.NONE);
		sc.setContent(cpChartable);
		setPosition(sc,3);

		cpChartable.setLayout(new GridLayout(COLUMNCOUNT,true));

		Composite commandbuttons=createCommandButtons(shell);
		setPosition(commandbuttons,4);
		
		Point size=groupCellStyle.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		shell.setSize(420,size.y*5+60);

		shell.setLocation(Display.getCurrent().getClientArea().width / 2 - shell.getSize().x/2, Display.getCurrent()
                .getClientArea().height / 2 - shell.getSize().y/2);
	}
	
	public String[] unitInBook(String book){
		Set<Integer> set=new HashSet<Integer>();
		
		for (NewCharTable nct:newcharList){
			if (nct.getBook().equals(book)){
				set.add(nct.getUnit());
			}
		}
		
		Integer temp[]=set.toArray(new Integer[0]);
		Arrays.sort(temp);
		
		String[] str=new String[temp.length];
		for (int i=0;i<temp.length;i++){
			str[i]=""+temp[i];
		}
		
		return str;
	}
	
	private Map<Character,Integer> charusedmap=new HashMap<Character,Integer>();
	private static Random RAND=new Random();
	
	public void putCharsToList(String str){
		char[] cs=str.toCharArray();
		for (char c:cs){
			if (!charlist.contains(c)){
				Integer t=charusedmap.get(c);
				charlist.add(new MyChar(c,(t==null?0:t.intValue())*1000+RAND.nextInt(1000)));
			}
		}
	}
	
	public void clearCharTable(){
		if (btChars==null)
			return;
		
		for (int i=0;i<btChars.length;i++){
			btChars[i].dispose();
			btChars[i]=null;
		}
		btChars=null;
		chooseCharList.clear();
		lbMessage.setText("");
	}
	
	public void updateCharTable(){
		String book=choosebook;
		Integer unitb=Integer.parseInt(cmbUnitb.getItem(chooseunitb));
		Integer unite=Integer.parseInt(cmbUnite.getItem(chooseunite));
		boolean read=btRange[1].getSelection();
		boolean write=btRange[0].getSelection();
		boolean lookup=btRange[2].getSelection();
		
		charlist.clear();
		for (NewCharTable nct:newcharList){
			if (book.equals(nct.getBook())&&unitb.compareTo(nct.getUnit())<=0&&unite.compareTo(nct.getUnit())>=0){
				if (write){
					putCharsToList(nct.getWrite());
				}
				if (read){
					putCharsToList(nct.getRead());
				}
				if (lookup){
					putCharsToList(nct.getLookup());
				}
			}
		}
		
		Collections.sort(charlist,new Comparator<MyChar>(){
			@Override
			public int compare(MyChar o1, MyChar o2) {
				return o1.getPriority()-o2.getPriority();
			}
		});
		
		for (MyChar c:charlist){
			System.out.println(c.getC()+"\t"+c.getPriority());
		}
		
		btChars=new Button[charlist.size()];
		int count=0;
		
		for (MyChar c:charlist){
			btChars[count]=new Button(cpChartable,SWT.CHECK);
			btChars[count].setData(c.getC());
			btChars[count].addSelectionListener(new SelectionAdapter(){
				public void widgetSelected(SelectionEvent e) {
					String t=e.getSource().toString();
					
					t=t.substring(t.indexOf('{')+1,t.indexOf('}'));
					charSelected(t.charAt(0));
				}
			});

			btChars[count++].setText(""+c.getC());
		}
		cpChartable.setSize(cpChartable.computeSize(SWT.DEFAULT, SWT.DEFAULT));
		cpChartable.layout();
	}
	
	public void charSelected(char c){
		if (chooseCharList.contains(c)){
			chooseCharList.remove(chooseCharList.indexOf(c));
		} else {
			chooseCharList.add(c);
		}
		
		lbMessage.setText("共选中[ "+chooseCharList.size()+"/"+maxChars+" ]个字.");
	}
	
	public void bookChanged(String book){
		cmbUnitb.removeAll();
		cmbUnite.removeAll();
		chooseunitb=-1;
		chooseunite=-1;
		
		setComboOptions(cmbUnitb,unitInBook(book));
		
		clearCharTable();
	}
	
	public void unitBeginChanged(int index){
		cmbUnite.removeAll();
		chooseunite=-1;

		String temp[]=cmbUnitb.getItems();
		
		String tt[]=new String[temp.length-index];
		System.arraycopy(temp, index, tt, 0, tt.length);
		
		setComboOptions(cmbUnite,tt);

		clearCharTable();
	}
	
	public void unitEndChanged(int index){
		clearCharTable();
		updateCharTable();
	}
	
	private String copybookModelDir;
	private String copybookDir;
	private void setCharsToSheet(String cellPattern,String fontname){
		String filename=copybookModelDir+properties.getProperty("模版.字帖."+cellPattern);
		
		Workbook wb=ExcelUtils.getWorkbook(filename);
		Sheet sheet=wb.getSheetAt(0);
		Row row=sheet.getRow(1);
		Cell cell=row.getCell(0);
		String today=new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		
		cell.setCellValue(today);
		
		row=sheet.getRow(2);
		cell=row.getCell(0);
		
		CellStyle style =cell.getCellStyle();
		Font font=wb.getFontAt(style.getFontIndex());
		System.out.println(font.getFontName()+font.getFontHeight());
		Font font1=wb.createFont();
		font1.setFontHeight(font.getFontHeight());
		font1.setFontName(fontname);
		font1.setColor(IndexedColors.BLACK.getIndex());
		Font font2=wb.createFont();
		font2.setFontHeight(font.getFontHeight());
		font2.setFontName(fontname);
		font2.setColor(IndexedColors.GREY_50_PERCENT.getIndex());
		
		CellStyle style1=wb.createCellStyle();
		style1.cloneStyleFrom(style);
		style1.setFont(font1);
		
		CellStyle style2=wb.createCellStyle();
		style2.cloneStyleFrom(style);
		style2.setFont(font2);
		
		int limit=chooseCharList.size()>maxChars?maxChars:chooseCharList.size();
		for (int i=0;i<limit;i++){
			String c=""+chooseCharList.get(i);
			if (i%2==0){
				row=sheet.getRow(i/2+2);
			}
			int begincell=7*(i%2);
			cell=row.getCell(begincell);
			cell.setCellStyle(style1);
			cell.setCellValue(c);
			for (int j=1;j<=grayChars;j++){
				cell=row.getCell(begincell+j);
				cell.setCellStyle(style2);
				cell.setCellValue(c);
			}
		}
		
		String outfilename=copybookDir+cellPattern+today+".xls";
		ExcelUtils.writeWorkbook(wb, outfilename);
	}
	
	public String createCopybook(){
		if (chooseCharList.isEmpty())
			return "未选中汉字";
		
		String fontname=null;
		for (Button b:btFont){
			if (b.getSelection()){
				fontname=b.getText();
				break;
			}
		}
		if (fontname==null)
			return "未选中字体";
		
		String cellPattern=null;
		for (Button b:btCellPattern){
			if (b.getSelection()){
				cellPattern=b.getText();
				break;
			}
		}
		if (cellPattern==null)
			return "未选中格子样式";
		
		setCharsToSheet(cellPattern,fontname);
		
		return null;
	}
	
	public void loadUsedChar(){
		File file=new File(copybookDir);
		String fns[]=file.list();
		if (fns==null||fns.length==0)
			return;
		for (String fn:fns){
			if (!(fn.toLowerCase().endsWith(".xls")||fn.toLowerCase().endsWith(".xlsx"))){
				continue;
			}
			loadExcelCopyBook(copybookDir+fn);
		}
		
	}
	
	public void loadExcelCopyBook(String fn){
		Workbook wb=ExcelUtils.getWorkbook(fn);
		Sheet sheet=wb.getSheet("Sheet0");
		for (int i=2;i<=21;i++){
			Row row=sheet.getRow(i);
			Cell cell=row.getCell(0);
			if (cell==null)
				break;
			String str=cell.getStringCellValue();
			if (str==null||str.trim().length()!=1)
				break;
			Character c=str.charAt(0);
			Integer ix=this.charusedmap.get(c);
			int ixx=(ix==null?0:ix.intValue());
			ixx++;
			charusedmap.put(c,ixx);
			
			cell=row.getCell(7);
			if (cell==null)
				break;
			str=cell.getStringCellValue();
			if (str==null||str.trim().length()!=1)
				break;
			c=str.charAt(0);
			ix=this.charusedmap.get(c);
			ixx=(ix==null?0:ix.intValue());
			ixx++;
			charusedmap.put(c,ixx);
		}
	}
	
	public List<NewCharTable> loadNewCharTable(String filename,String charset){
		List<NewCharTable> nctl=new ArrayList<NewCharTable>();
		List<String> strings=loadTextFile(filename,charset);
		if (strings==null)
			return nctl;
		
		booklist.clear();
		for (String str:strings){
			String[] tt=str.split(",");
			if (tt.length<4)
				continue;
			NewCharTable nct=new NewCharTable();
			nct.setBook(tt[0]);
			nct.setUnit(Integer.parseInt(tt[1].trim()));
			nct.setWrite(tt[2]);
			nct.setRead(tt[3]);
			if (tt.length>=5)
				nct.setLookup(tt[4]);
			else
				nct.setLookup("");
			nctl.add(nct);
			
			if (!booklist.contains(nct.getBook())){
				booklist.add(0, nct.getBook());
			}
		}
		
		return nctl;
	}
	
	public static void main(String[] args) {
		Display display=new Display();
		final Shell shell=new Shell(display);
		DialogCopybook dc=new DialogCopybook(shell);
		Properties p=new Properties();
		try {
			p.load(new FileReader("d:/studyassist/config/studyassist.properties"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		dc.setProperties(p);
		
		dc.setNewcharList(dc.loadNewCharTable(p.getProperty("生字表文件名"),"GBK"));

		dc.open();
		

	}


}
